'Copyright (C) 2009 Christiaan Cable
'
'This program is free software; you can redistribute it and/or
'modify it under the terms of the GNU General Public License
'as published by the Free Software Foundation; either version 3
'of the License, or (at your option) any later version.
'
'This program is distributed in the hope that it will be useful,
'but WITHOUT ANY WARRANTY; without even the implied warranty of
'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'GNU General Public License for more details (LICENCE.TXT).

'Modified by DD32 18/9/07, 17/01/08, 21/01/08, 20/02/08

Imports System.Net
Imports System.Windows.Forms
Imports System.Text.RegularExpressions

Public Class AAPTNew
    Public ISPReturnData As New ISPReturnData
    Private CookieContainer As New System.Net.CookieContainer
    Private cCache As New CredentialCache 'Not used; Simply for the methods in app.

    Public Sub New(ByVal ConfigurationData As ConfigurationData)

        Try
            'set rollover date
            SetRolloverDate(ConfigurationData, ISPReturnData)

            Dim strHTMLData As String = ""
            Dim postData As String = ""
            Dim URL As String = ""

            Dim OfferID As Integer = 0

            ''Login into AAPTs master system, This sets us as "Online" in the admin console, without this, we cant log into the usage console
            postData = "targetApp=selfserv&referrer=&forwardUrl=https%3A%2F%2Fwww.aapt.com.au%2FHelp_Yourself%2F&securityQuestInd=N&x=17&y=18" & _
                        "&username=" & ConfigurationData.Username & "&password=" & ConfigurationData.Password
            URL = "https://www2.aapt.com.au/signin/dispatcher.asp?forwardUrl=/unBilledItemizedOfferDetailsAction.do&action=retrieveUnBilledItemizedOfferDetails"
            strHTMLData = ISPPost(URL, postData, CookieContainer, cCache, "application/x-www-form-urlencoded", URL) ''Needs a referer, itself will do

            ''Login into the "View my usage" page
            Dim refererURL As String = "https://www2.aapt.com.au/signin/DispatcherWait.asp?forwardUrl=/unBilledItemizedOfferDetailsAction.do&action=retrieveUnBilledItemizedOfferDetails"

            postData = "username=" & ConfigurationData.Username & "&password=" & ConfigurationData.Password
            URL = "https://helpyourself.aapt.com.au/csc/login.do?forwardUrl=/unBilledItemizedOfferDetailsAction.do&action=retrieveUnBilledItemizedOfferDetails"
            strHTMLData = ISPPost(URL, postData, CookieContainer, cCache, "application/x-www-form-urlencoded", refererURL) ''Requires a referer from the Login Dispatcher script, can safely be hard coded

            If UA.DebugISP = True Then My.Computer.FileSystem.WriteAllText(GetAppDataPath() & "debug.htm", strHTMLData, False, System.Text.Encoding.ASCII)

            If strHTMLData.Contains("The user doesn't exist") Then
                ISPReturnData.ErrorMessage = "Login Failed"
                Exit Sub
            End If

            '' Search out the URL of the usage page for the Broadband connection
            Dim tblMatches As MatchCollection
            'Find the usage table
            Dim tblRegex As New Regex("<table.*?id=""vbtable1"">(.*?)</table>", RegexOptions.Singleline)
            tblMatches = tblRegex.Matches(strHTMLData)

            Dim tableHTML As String = tblMatches.Item(0).Value

            'Find the usage table rows
            tblRegex = New Regex("<tr.*?>(.*?)</tr>", RegexOptions.Singleline)
            tblMatches = tblRegex.Matches(tableHTML)

            If tblMatches.Count = 0 Then
                ''No matches = Not a login
                ISPReturnData.ErrorMessage = "No Products Found"
                Exit Sub
            End If

            Dim successfulMatch As Match
            For Each successfulMatch In tblMatches
                If successfulMatch.Groups(1).Value.IndexOf("@") > -1 Then ''Not all plans include "Broadband"
                    tableHTML = successfulMatch.Groups(1).Value

                    ' Dim PlanName As String = "" 'Not needed anymore.
                    ' PlanName = ExtractText(tableHTML, "<a", 0, ">", "</a>")
                    OfferID = CInt(ExtractText(tableHTML, "<a", 0, "customizedOfferId=", "&"))

                    tblRegex = New Regex("<td.*?>(.*?)</td>", RegexOptions.Singleline)
                    tblMatches = tblRegex.Matches(tableHTML)

                    ''Do the Billing Date
                    Dim dateRegex As New Regex("billing date which is\s+([\d\/]+)", RegexOptions.IgnoreCase)
                    ISPReturnData.LastUpdated = Now

                    '' TODO: Safe to remove the following code branch > February hopefully.
                    '' Fix for End month is < than last updated. 
                    '' The month must've rolled over, but AAPT's systems havnt got around to archiving the old usage.. 
                    '' Therefor, flip forward a month from the original date
                    '' Feb: I had the same problem again, Lets see next month.

                    ISPReturnData.PeakDownload = GB2MB(ExtractText(tblMatches.Item(1).Value, "<", 0, ">", "<")) 'Not included in cap.. Usually uploads "Outside of cap"
                    ISPReturnData.PeakUpload = GB2MB(ExtractText(tblMatches.Item(2).Value, "<", 0, ">", "<")) 'Used Quota "Used from cap"

                    Exit For ' No point looking at any extra items that the user has, this will also mean we use the _first_ broadband connection that we find in the users account
                End If
            Next

            If OfferID = 0 Then
                '' No BB connection could be found.
                ISPReturnData.ErrorMessage = "Sorry, No ADSL products could be found"
                Exit Sub
            End If

            '##########################################################

            ProcessISPData(ConfigurationData, ISPReturnData)

            'check for error
            If ISPReturnData.ErrorMessage <> "" Then Exit Sub

            '##########################################################

            'create graph data

            'usage
            ISPReturnData.GraphItemList.Add(New GraphItem("Usage " & Format(System.Math.Floor((ISPReturnData.PeakDownload / Val(ConfigurationData.PeakUsageLimit)) * 1000) / 10, "#0.0") & "% (" & ISPReturnData.PeakDownload & " MB)", ISPReturnData.PeakDownload, CSng(Val(ConfigurationData.PeakUsageLimit)), False))

            'days elapsed
            ISPReturnData.GraphItemList.Add(New GraphItem("Days Elapsed " & Format((ISPReturnData.DaysUsed / (ISPReturnData.DaysUsed + ISPReturnData.DaysLeft)) * 100, "#0") & "% (" & ISPReturnData.DaysUsed & " Days)", ISPReturnData.DaysUsed, ISPReturnData.DaysUsed + ISPReturnData.DaysLeft, False))

            '##########################################################

            'create stats data
            ISPReturnData.TextItemList.Add(New TextItem("Usage Left :", ISPReturnData.PeakUsageRemainingDescription))
            ISPReturnData.TextItemList.Add(New TextItem("Usage Avg. Left :", ISPReturnData.PeakUsageRemainingPerDayDescription))

            If ISPReturnData.ShapedNow = False Then
                ISPReturnData.TextItemList.Add(New TextItem("Shaped :", "NO"))
            Else
                ISPReturnData.TextItemList.Add(New TextItem("Shaped :", "YES"))
            End If

            If ISPReturnData.PeakUpload > 0 Then
                If (ISPReturnData.PeakUpload > 1024) Then
                    ISPReturnData.TextItemList.Add(New TextItem("Uncounted :", Format(ISPReturnData.PeakUpload / 1024, "#0.00") + " GB"))
                Else
                    ISPReturnData.TextItemList.Add(New TextItem("Uncounted :", Format(ISPReturnData.PeakUpload, "#0.0") + " MB"))
                End If
            End If

            '##########################################################

            'process alerts
            ProcessAlerts(ConfigurationData, ISPReturnData)

        Catch ex As Exception
            ISPReturnData.ErrorMessage = ex.Message + ex.ToString
        End Try
    End Sub

    Function GB2MB(ByVal valin As String) As Integer

        If valin.IndexOf("(") > 0 Then 'If value has a ( in it, The MB version must be following the GB version.
            valin = valin.Substring(valin.IndexOf("(")) ' Find the start of the MB version
            valin = valin.Replace("(", "").Replace(")", "").Replace(",", "") 'Strip out the Commas and brackets.
        End If

        valin = TrimComplete(valin)

        Dim valout As Double = 0
        Dim Size As String = "GB"

        If InStr(valin, "GB") > 0 Or InStr(valin, "MB") > 0 Then
            Size = Right(valin, 2)
            valin = Left(valin, Len(valin) - 2)
            valout = CDbl(valin)
        ElseIf InStr(valin, "B") > 0 Then
            Size = Right(valin, 1)
            valin = Left(valin, Len(valin) - 1)
            valout = CDbl(valin)
        End If
        If "GB" = Size Then
            valout *= 1024
        ElseIf "MB" = Size Then
            'valout = valout 'nothing
        ElseIf "B" = Size Then
            valout /= 1024
        End If
        Debug.Print(Size + " " + CStr(valin) + " " + CStr(valout))

        Return CInt(valout)
    End Function

    Public Function TrimComplete(ByVal sValue As String) As String 'Source: http://www.freevbcode.com/ShowCode.Asp?ID=104
        'Trims all non-printable characters(including space's)
        Dim sAns As String
        Dim sChar As String
        Dim lLen As Integer
        Dim lCtr As Integer

        sAns = sValue
        lLen = Len(sValue)

        If lLen > 0 Then
            'Ltrim
            For lCtr = 1 To lLen
                sChar = Mid(sAns, lCtr, 1)
                If Asc(sChar) > 32 Then Exit For
            Next

            sAns = Mid(sAns, lCtr)
            lLen = Len(sAns)

            'Rtrim
            If lLen > 0 Then
                For lCtr = lLen To 1 Step -1
                    sChar = Mid(sAns, lCtr, 1)
                    If Asc(sChar) > 32 Then Exit For
                Next
            End If
            sAns = Left$(sAns, lCtr)
        End If

        TrimComplete = sAns

    End Function
End Class
